﻿using System.Linq;
using System.Web.Mvc;
using System.Web.Helpers;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using PlanetTelex.Coverflow.Models;
using PlanetTelex.Coverflow.Services;
using PlanetTelex.Coverflow.ViewModels;

namespace PlanetTelex.Coverflow.Drivers
{
    /// <summary>
    /// A driver defines associations of shapes to display for each context the part can render.
    /// </summary>
    public class CoverflowDriver : ContentPartDriver<CoverflowPart>
    {
        private readonly ICoverflowService _coverflowService;

        /// <summary>
        /// Initializes a new instance of the <see cref="CoverflowDriver"/> class.
        /// </summary>
        /// <param name="coverflowService">The coverflow service.</param>
        public CoverflowDriver(ICoverflowService coverflowService)
        {
            _coverflowService = coverflowService;
        }
        
        /// <summary>
        /// Defines the shapes required for the part's main view.
        /// </summary>
        /// <param name="part">The part.</param>
        /// <param name="displayType">The display type.</param>
        /// <param name="shapeHelper">The shape helper.</param>
        protected override DriverResult Display(CoverflowPart part, string displayType, dynamic shapeHelper)
        {
            var viewModel = new CoverflowViewModel();
            if (part != null && displayType.Contains("Detail"))
            {
                bool categoriesEnabled = false;
                if (!string.IsNullOrEmpty(part.SettingsJson))
                {
                    var options = Json.Decode(part.SettingsJson);
                    categoriesEnabled = options.categories.enabled;
                    viewModel.SettingsJson = MvcHtmlString.Create(part.SettingsJson);
                }
                viewModel.CoverflowId = "coverflow_" + part.ContentItem.Id;
                viewModel.Covers = _coverflowService.ListAllCovers(part.BasePath, categoriesEnabled);
            }
            return ContentShape("Parts_Coverflow", () => shapeHelper.DisplayTemplate(TemplateName: "Parts/Coverflow", Model: viewModel, Prefix: Prefix));
        }

        /// <summary>
        /// Defines the shapes required for the editor view.
        /// </summary>
        /// <param name="part">The part.</param>
        /// <param name="shapeHelper">The shape helper.</param>
        protected override DriverResult Editor(CoverflowPart part, dynamic shapeHelper)
        {
            if (part == null)
                part = new CoverflowPart();

            var categoriesEnabled = false;
            if (!string.IsNullOrEmpty(part.SettingsJson))
            {
                var options = Json.Decode(part.SettingsJson);
                categoriesEnabled = options.categories.enabled;
            }

            var allMediaFolders = _coverflowService.ListAllMediaFolders();
            if (allMediaFolders != null)
                part.AllMediaFolders = allMediaFolders.Select(o => new SelectListItem { Text = o.MediaPath, Value = o.MediaPath });

            part.Covers = _coverflowService.ListAllCovers(part.BasePath, categoriesEnabled);
            if (!string.IsNullOrEmpty(part.BasePath))
                part.SelectedMediaFolder = part.BasePath;
            
            return ContentShape("Parts_Coverflow_Edit", () => shapeHelper.EditorTemplate(TemplateName: "Parts/Coverflow", Model: part, Prefix: Prefix));
        }

        /// <summary>
        /// Runs upon the POST of the editor view.
        /// </summary>
        /// <param name="part">The part.</param>
        /// <param name="updater">The updater.</param>
        /// <param name="shapeHelper">The shape helper.</param>
        protected override DriverResult Editor(CoverflowPart part, IUpdateModel updater, dynamic shapeHelper)
        {
            if (part == null || updater == null)
                return Editor(null, shapeHelper);

            updater.TryUpdateModel(part, Prefix, null, null);
            string selectedFolder = part.SelectedMediaFolder != CoverflowService.SelectFolder
                                        ? part.SelectedMediaFolder
                                        : string.Empty;

            part.BasePath = selectedFolder;
            return Editor(part, shapeHelper);
        }
    }
}
